{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "4f49fdc8",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "# Option Pricing Using Amplitude Estimation\n",
    "\n",
    "This notebook demonstrates how to use the `construct_finance_model` function, which constructs an option pricing model. For more comprehensive explanation on the algorithm see [Option Pricing notebook](https://github.com/Classiq/classiq-library/blob/main/applications/finance/option_pricing/option_pricing.ipynb).\n",
    "\n",
    "\n",
    "Option pricing deals with evaluating average values $E[f(x)]$, where $f$ is some financial payoff function, and the probability distribution is given. A quantum algorithm for this task is the Amplitude Estimation algorithm, which can estimate the average with a\n",
    "convergence rate of $\\Omega(1/M^{1/2})$, compared to $\\Omega(1/M)$ in the classical case, where $M$ is the number of Grover iterations in the quantum case and the number of the Monte Carlo samples in the classical case. This represents a theoretical quadratic speed-up of the quantum method over classical Monte Carlo methods."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a93bd20c-1e05-4bd6-ad60-8a1242216414",
   "metadata": {},
   "source": [
    "## 1. Defining a Financial Function Input"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d1caaed6-363b-49f8-b99e-c834f7d7eaac",
   "metadata": {},
   "source": [
    "First, we define the probability distribution. The constructor function supports two different built-in functions, a log-normal distribution, or a Gaussian one. In the example below we choose the former:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "cff0e5d1-a30a-4186-be89-351db593df3a",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-07T13:20:51.942440Z",
     "iopub.status.busy": "2024-05-07T13:20:51.941220Z",
     "iopub.status.idle": "2024-05-07T13:20:54.668569Z",
     "shell.execute_reply": "2024-05-07T13:20:54.667925Z"
    }
   },
   "outputs": [],
   "source": [
    "from classiq.applications.finance import log_normal_model_input\n",
    "\n",
    "num_qubits = 5\n",
    "mu = 0.7\n",
    "sigma = 0.13\n",
    "\n",
    "log_normal_model = log_normal_model_input.LogNormalModelInput(\n",
    "    num_qubits=num_qubits, mu=mu, sigma=sigma\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "951d079d-90a1-4791-bd0f-40a50dd4fcd9",
   "metadata": {},
   "source": [
    "Next, we define the payoff function. The constructor supports two built-in payoff functions: European Call Option or Value at Risk:\n",
    "\n",
    "$f_{\\rm european}(S)=\\\n",
    "\\Bigg\\{\\begin{array}{lr}\n",
    "    0, & \\text{when } K\\geq S\\\\\n",
    "    S - K, & \\text{when } K < S\\end{array},\n",
    "$\n",
    "\n",
    "$f_{\\rm var}(S)=\\\n",
    "\\Bigg\\{\\begin{array}{lr}\n",
    "    0, & \\text{when } K\\geq S\\\\\n",
    "    1, & \\text{when } K < S\\end{array}.\n",
    "$\n",
    "\n",
    "This notebook demonstrates for the European Call Option."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "986b9ce8",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-07T13:20:54.671519Z",
     "iopub.status.busy": "2024-05-07T13:20:54.671105Z",
     "iopub.status.idle": "2024-05-07T13:20:54.674920Z",
     "shell.execute_reply": "2024-05-07T13:20:54.674370Z"
    },
    "pycharm": {
     "name": "#%%\n"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "from classiq.applications.finance import function_input\n",
    "\n",
    "threshold = 2\n",
    "\n",
    "condition = function_input.FunctionCondition(threshold=threshold, larger=True)\n",
    "finance_function = function_input.FinanceFunctionInput(\n",
    "    f=\"european call option\",\n",
    "    condition=condition,\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bbb7834c",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "## 2. Constructing and Synthesizing a Finance Model\n",
    "\n",
    "Finally, we construct the model using the `construct_finance_model` function. We pass the `phase_port_size` which will set the accuracy of the calculation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "bd2d44b5",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-07T13:20:54.677294Z",
     "iopub.status.busy": "2024-05-07T13:20:54.676909Z",
     "iopub.status.idle": "2024-05-07T13:20:54.684777Z",
     "shell.execute_reply": "2024-05-07T13:20:54.684194Z"
    },
    "pycharm": {
     "name": "#%%\n"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "from classiq import construct_finance_model\n",
    "\n",
    "qmod = construct_finance_model(\n",
    "    finance_model_input=log_normal_model,\n",
    "    finance_function_input=finance_function,\n",
    "    phase_port_size=1,\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "6cd58adc-4cc0-4030-9458-7b295b6f4f0d",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-07T13:20:54.687304Z",
     "iopub.status.busy": "2024-05-07T13:20:54.686844Z",
     "iopub.status.idle": "2024-05-07T13:20:54.696455Z",
     "shell.execute_reply": "2024-05-07T13:20:54.695861Z"
    }
   },
   "outputs": [],
   "source": [
    "from classiq import write_qmod\n",
    "\n",
    "write_qmod(qmod, \"option_pricing\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7fd2f677",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "We synthesize and visualize the circuit"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "b74362c6-0045-4480-b6e7-306dcf2df559",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-07T13:20:54.698878Z",
     "iopub.status.busy": "2024-05-07T13:20:54.698525Z",
     "iopub.status.idle": "2024-05-07T13:20:59.318282Z",
     "shell.execute_reply": "2024-05-07T13:20:59.317522Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Opening: https://platform.classiq.io/circuit/a57d2c5e-b2e1-4918-8c4c-7ca30fb27d56?version=0.41.0.dev39%2B79c8fd0855\n"
     ]
    }
   ],
   "source": [
    "from classiq import show, synthesize\n",
    "\n",
    "qprog = synthesize(qmod)\n",
    "show(qprog)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cf831b22",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "## 3. Executing to Find the Average Value"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "3c927939-f26d-4a71-bfac-4b89c6ba603e",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-07T13:20:59.322538Z",
     "iopub.status.busy": "2024-05-07T13:20:59.321863Z",
     "iopub.status.idle": "2024-05-07T13:21:01.729858Z",
     "shell.execute_reply": "2024-05-07T13:21:01.729203Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "from classiq import execute\n",
    "\n",
    "results = execute(qprog).result()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bafef6e4",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "Printing out the result estimation of the options price :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "3b4c29f4-ff42-4120-a6e1-f7b0362bfe6c",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-07T13:21:01.732574Z",
     "iopub.status.busy": "2024-05-07T13:21:01.732252Z",
     "iopub.status.idle": "2024-05-07T13:21:01.736061Z",
     "shell.execute_reply": "2024-05-07T13:21:01.735368Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "estimation : 0.3509999999999999\n"
     ]
    }
   ],
   "source": [
    "print(results[1].name, \":\", results[1].value)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.9"
  },
  "vscode": {
   "interpreter": {
    "hash": "a07aacdcc8a415e7643a2bc993226848ff70704ebef014f87460de9126b773d0"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
